/**
 * 
 */
package com.demo2do.cda.admin.visitor.impl;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;

import com.demo2do.cda.admin.entity.security.Menu;
import com.demo2do.cda.admin.entity.security.Role;
import com.demo2do.core.utils.CollectionUtils;
import com.demo2do.core.utils.JsonUtils;

/**
 * 
 * @author downpour
 *
 */
@Component("secureVisitor")
public class SecureVisitor {
    
    private static final Logger logger = LoggerFactory.getLogger(SecureVisitor.class);

    /**
     * Get all menus as a list
     * 
     * @return
     */
    @Cacheable("menus")
    public List<Menu> getMenus() {

        logger.debug("#getMenus() - parse menus from menus.json");
        
        try {
            
            Resource resource = new ClassPathResource("cache/menus.json");
            
            return JsonUtils.parseAsList(resource.getFile(), Menu.class);
        
        } catch (Exception e) {
            logger.error("#getMenus() - find error when parsing menus.json", e);
            return null;
        }

    }

    /**
     * Get all submenus as a list
     * 
     * @return
     */
    @Cacheable("submenus")
    public Map<String, List<Menu>> getSubmenus() {

         logger.debug("#getSubmenus() - parse submenus from submenus.json");

         try {
             
             Resource resource = new ClassPathResource("cache/submenus.json");
             
             List<Menu> menus = JsonUtils.parseAsList(resource.getFile(), Menu.class);
             
             return CollectionUtils.constructMapValues(menus, "key"); 
         
         } catch (Exception e) {
             logger.error("#getSubmenus() - find error when parsing submenus.json", e);
             return null;
         }

    }
    
    /**
     * Get all roles group by name and alias
     * 
     * @return
     */
    @Cacheable("roles")
    public Map<String, Role> getRoles() {
        
        try {
            
            Resource resource = new ClassPathResource("cache/roles.json");
            
            List<Role> roles = JsonUtils.parseAsList(resource.getFile(), Role.class);
            Map<String, Role> result = new LinkedHashMap<String, Role>(roles.size() * 2);
            for(Role role : roles) {
                result.put(role.getName(), role);
                result.put(role.getAlias(), role);
            }
            
            return result; 
        
        } catch (Exception e) {
            
            logger.error("#getRoles() - find error when parsing roles.json", e);
            
            return null;
            
        }
        
    }

    /**
     * 
     * The actual return type is Map<String, Map<String, List<String>>>
     * 
     * @return
     */
    @Cacheable("resources")
    public Map<String, Object> getResources() {
        
        logger.debug("#getResources() - parse resources from resources.json");

        try {
            
            Resource resource = new ClassPathResource("cache/resources.json");
            
            return JsonUtils.parse(resource.getFile());
        
            
        } catch (Exception e) {
            logger.error("#getSubmenus() - find error when parsing resources.json", e);
            return null;
        }

    }
    
}
